import 'dart:io';
import 'dart:typed_data';

import 'package:intl/intl.dart';
import 'package:path_provider/path_provider.dart';

class FileUtil {
  static String getFileDateTime(int? timestamp) {
    DateTime dateTime;
    if (timestamp == null) {
      dateTime = DateTime.now();
    } else {
      dateTime = DateTime.fromMillisecondsSinceEpoch(timestamp);
    }

    return DateFormat('yyyy-MM-dd HH:mm').format(dateTime);
  }

  static String second2MS(int second) {
    String ms = "00:00";
    if (second > 0) {
      int m = second ~/ 60;
      int s = second % 60;
      ms = "${zeroFill(m)}:${zeroFill(s)}";
    }
    return ms;
  }

  static String second2HMS(int sec) {
    String hms = "00:00:00";
    if (sec > 0) {
      int h = sec ~/ 3600;
      int m = (sec % 3600) ~/ 60;
      int s = sec % 60;
      hms = "${zeroFill(h)}:${zeroFill(m)}:${zeroFill(s)}";
    }
    return hms;
  }

  static String zeroFill(int i) {
    return i >= 10 ? "$i" : "0$i";
  }

  static Future<String> saveImageToLocal(String imageName, Uint8List imageBytes) async {
    final directory = await getApplicationDocumentsDirectory();
    final directoryPath = '${directory.path}/img';
    final Directory dir = Directory(directoryPath);
    bool isExist = await dir.exists();
    if (!isExist) {
      await Directory(directoryPath).create(recursive: true);
    }
    final path = '${dir.path}/$imageName.png';
    final file = File(path);
    await file.writeAsBytes(imageBytes);
    return file.path;
  }

  /*
  修改文件的后缀名
   */
  static Future<String> changeFileExtension(String filePath, String newExtension) async {
    int lastIndex = filePath.lastIndexOf('/');
    String path = filePath.substring(0, lastIndex);
    String fileName = filePath.substring(lastIndex + 1);
    int dotIndex = fileName.lastIndexOf('.');
    String withoutExtensionName = fileName.substring(0, dotIndex);
    String extension = fileName.substring(dotIndex + 1);
    // 组合新的文件路径
    var newFilePath = "$path/$withoutExtensionName.$newExtension";
    // 重命名文件
    File file = await File(filePath).rename(newFilePath);
    return file.absolute.path;
  }

  /*
  删除指定文件
   */
  static Future<void> deleteFile(String filePath) async {
    final file = File(filePath);
    if (await file.exists()) {
      await file.delete();
    }
  }

  static Future<void> copyFileToDirectory(String filePath) async {
    final directory = await getApplicationDocumentsDirectory();
    final directoryPath = '${directory.path}/file';
    final Directory dir = Directory(directoryPath);
    bool isExist = await dir.exists();
    if (!isExist) {
      await Directory(directoryPath).create(recursive: true);
    }
    final file = File(filePath);
    final targetFile = File('$dir/${file.path.split('/').last}');
    await file.copy(targetFile.path);
  }

  static Future<void> writeFile(String filePath, String content) async {
    final file = File(filePath);
    if (await file.exists()) {
      // await file.writeAsString(content, mode: FileMode.append);
      final sink = file.openWrite(mode: FileMode.writeOnlyAppend);
      sink.writeln(content);
    }
  }

  static Future<void> copyFile(String fromPath, toPath) async {
    final File toFile = File('$toPath');
    await toFile.writeAsBytes(await File(fromPath).readAsBytes());
  }

  /*
  清空文件夹
   */
  static Future<void> clearFolder(String folderPath) async {
    final Directory directory = Directory(folderPath);
    if (await directory.exists()) {
      final List<FileSystemEntity> files = directory.listSync();
      for (final FileSystemEntity file in files) {
        if (file is File) {
          await file.delete();
        } else if (file is Directory) {
          await clearFolder(file.path);
        }
      }
    }
  }

  static Future<String> saveUint8ListToFile(Uint8List data) async {
    final directory = await getApplicationDocumentsDirectory();
    final directoryPath = '${directory.path}/thumbnail';
    final Directory dir = Directory(directoryPath);
    bool isExist = await dir.exists();
    if (!isExist) {
      await Directory(directoryPath).create(recursive: true);
    }
    final filePath = '$directoryPath/thumbnail-${DateTime.now().millisecondsSinceEpoch}.png';
    final file = File(filePath);
    await file.writeAsBytes(data);
    return filePath;
  }

  static bool isGratter8M(int fileSize) {
    return fileSize < 1024 * 1024 * 8;
  }

  static String getNoSuffixName(String fileName) {
    String name = fileName;
    final lastIndex = fileName.lastIndexOf('.');
    if (lastIndex != -1) {
      name = name.substring(0, lastIndex);
    }
    return name;
  }

  static String getSuffix(String fileName) {
    String name = fileName;
    final lastIndex = fileName.lastIndexOf('.');
    if (lastIndex != -1 && name.length > lastIndex + 1) {
      name = name.substring(lastIndex + 1);
    }
    return name;
  }

  static String convertFileSize(int fileSize) {
    String fileSizeStr = "";
    double kSize = 1024;
    double mSize = 1048576;
    double gSize = 1073741824;
    if (fileSize < kSize) {
      fileSizeStr = '${fileSize}B';
    } else if (fileSize < mSize) {
      fileSizeStr = '${(fileSize / kSize).toStringAsFixed(0)}kb';
    } else if (fileSize < gSize) {
      fileSizeStr = '${(fileSize / mSize).toStringAsFixed(0)}M';
    } else {
      fileSizeStr = '${(fileSize / gSize).toStringAsFixed(0)}G';
    }
    return fileSizeStr;
  }

  static Future<String> getDownLoadDirectory() async {
    final directory = await getApplicationDocumentsDirectory();
    final directoryPath = '${directory.path}/image';
    final Directory dir = Directory(directoryPath);
    bool isExist = await dir.exists();
    if (!isExist) {
      await Directory(directoryPath).create(recursive: true);
    }
    return directoryPath;
  }

  static String formatOutputTime() {
    var now = DateTime.now();
    var formatter = DateFormat('yy-MM-dd_HH:mm:ss');
    String formatted = formatter.format(now);
    return formatted;
  }

  /*
  图片视频缓存路径
   */
  static Future<String> getImageVideoDirectory() async {
    final directory = await getApplicationDocumentsDirectory();
    final directoryPath = '${directory.path}/image-video';
    final Directory dir = Directory(directoryPath);
    bool isExist = await dir.exists();
    if (!isExist) {
      await Directory(directoryPath).create(recursive: true);
    }
    return directoryPath;
  }

  static Future<String> getImageTmpImgDirectory() async {
    final directory = await getApplicationDocumentsDirectory();
    final directoryPath = '${directory.path}/images';
    final Directory dir = Directory(directoryPath);
    bool isExist = await dir.exists();
    if (!isExist) {
      await Directory(directoryPath).create(recursive: true);
    }
    return directoryPath;
  }

  static Future<File?> createFile(String filename) async {
    final File file = File(filename);
    if (await file.exists()) {
      return file;
    }
    try {
      await file.create();
    } catch (e) {
      return null;
    }
    return file;
  }

  /*
  临时缓存目录
   */
  static Future<String> getTmpDirectory() async {
    final directory = await getApplicationDocumentsDirectory();
    final directoryPath = '${directory.path}/tmp';
    final Directory dir = Directory(directoryPath);
    bool isExist = await dir.exists();
    if (!isExist) {
      await Directory(directoryPath).create(recursive: true);
    }
    return directoryPath;
  }

  /*
  编辑视频输出路径
   */
  static Future<String> getOutputVideoDirectory() async {
    final directory = await getApplicationDocumentsDirectory();
    final directoryPath = '${directory.path}/output';
    final Directory dir = Directory(directoryPath);
    bool isExist = await dir.exists();
    if (!isExist) {
      await Directory(directoryPath).create(recursive: true);
    }
    return directoryPath;
  }
}
